package com.employment.controller;

import com.employment.dto.ApplicationSearchDTO;
import com.employment.dto.JobApplicationDTO;
import com.employment.dto.Result;
import com.employment.entity.JobApplication;
import com.employment.security.UserPrincipal;
import com.employment.service.JobApplicationService;
import com.mybatisflex.core.paginate.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 求职申请控制器
 * 
 * @author Employment System
 * @since 1.0.0
 */
@Tag(name = "求职申请", description = "求职申请相关接口")
@RestController
@RequestMapping("/api/applications")
@RequiredArgsConstructor
public class JobApplicationController {

    private final JobApplicationService jobApplicationService;

    @Operation(summary = "投递简历", description = "求职者投递简历申请职位")
    @PostMapping
    @PreAuthorize("hasAnyRole('JOBSEEKER', 'ADMIN')")
    public Result<JobApplication> applyJob(@Validated @RequestBody JobApplicationDTO applicationDTO,
                                         @AuthenticationPrincipal UserPrincipal userPrincipal) {
        // 检查是否已申请过该职位
        if (jobApplicationService.hasApplied(userPrincipal.getUserId(), applicationDTO.getJobId())) {
            return Result.badRequest("您已申请过该职位，请勿重复申请");
        }
        
        JobApplication jobApplication = new JobApplication();
        BeanUtils.copyProperties(applicationDTO, jobApplication);
        jobApplication.setUserId(userPrincipal.getUserId());
        
        boolean success = jobApplicationService.applyJob(jobApplication);
        if (success) {
            return Result.success("申请成功", jobApplication);
        }
        return Result.error("申请失败");
    }

    @Operation(summary = "撤回申请", description = "求职者撤回申请")
    @PostMapping("/{applicationId}/withdraw")
    @PreAuthorize("hasAnyRole('JOBSEEKER', 'ADMIN')")
    public Result<Void> withdrawApplication(@Parameter(description = "申请ID") @PathVariable Long applicationId,
                                          @AuthenticationPrincipal UserPrincipal userPrincipal) {
        boolean success = jobApplicationService.withdrawApplication(applicationId, userPrincipal.getUserId());
        if (success) {
            return Result.success("撤回成功");
        }
        return Result.error("撤回失败");
    }

    @Operation(summary = "申请详情", description = "查询申请详细信息")
    @GetMapping("/{applicationId}")
    public Result<JobApplication> getApplicationById(@Parameter(description = "申请ID") @PathVariable Long applicationId,
                                                   @AuthenticationPrincipal UserPrincipal userPrincipal) {
        JobApplication application = jobApplicationService.getApplicationById(applicationId);
        if (application != null) {
            // 企业用户查看时，标记为已查看
            if (userPrincipal.isCompanyUser()) {
                jobApplicationService.viewApplication(applicationId, userPrincipal.getUserId());
            }
            return Result.success(application);
        }
        return Result.notFound();
    }

    @Operation(summary = "我的申请", description = "查询当前用户的申请列表")
    @PostMapping("/my")
    @PreAuthorize("hasAnyRole('JOBSEEKER', 'ADMIN')")
    public Result<Page<JobApplication>> getMyApplications(@RequestBody ApplicationSearchDTO searchDTO,
                                                          @AuthenticationPrincipal UserPrincipal userPrincipal) {
        Page<JobApplication> page = new Page<>(searchDTO.getCurrent(), searchDTO.getSize());

        Page<JobApplication> result = jobApplicationService.getUserApplicationPage(
                page, userPrincipal.getUserId(), searchDTO.getStatus());
        
        return Result.success(result);
    }

    @Operation(summary = "公司收到的申请", description = "查询公司收到的申请列表")
    @PostMapping("/company")
    @PreAuthorize("hasAnyRole('COMPANY', 'ADMIN')")
    public Result<Page<JobApplication>> getCompanyApplications(@RequestBody ApplicationSearchDTO searchDTO,
                                                              @AuthenticationPrincipal UserPrincipal userPrincipal) {
        Page<JobApplication> page = new Page<>(searchDTO.getCurrent(), searchDTO.getSize());

        Page<JobApplication> result = jobApplicationService.getCompanyApplicationPage(
                page, searchDTO.getCompanyId(), searchDTO.getJobId(), searchDTO.getStatus());
        
        return Result.success(result);
    }

    @Operation(summary = "回复申请", description = "企业回复求职申请")
    @PostMapping("/{applicationId}/reply")
    @PreAuthorize("hasAnyRole('COMPANY', 'ADMIN')")
    public Result<Void> replyApplication(@Parameter(description = "申请ID") @PathVariable Long applicationId,
                                       @RequestBody JobApplicationDTO applicationDTO,
                                       @AuthenticationPrincipal UserPrincipal userPrincipal) {
        boolean success = jobApplicationService.replyApplication(
                applicationId,
                applicationDTO.getReplyContent(),
                applicationDTO.getStatus(),
                userPrincipal.getUserId()
        );
        
        if (success) {
            return Result.success("回复成功");
        }
        return Result.error("回复失败");
    }

    @Operation(summary = "发送面试邀请", description = "企业发送面试邀请")
    @PostMapping("/{applicationId}/interview")
    @PreAuthorize("hasAnyRole('COMPANY', 'ADMIN')")
    public Result<Void> sendInterviewInvitation(@Parameter(description = "申请ID") @PathVariable Long applicationId,
                                              @RequestBody JobApplicationDTO applicationDTO,
                                              @AuthenticationPrincipal UserPrincipal userPrincipal) {
        applicationDTO.setApplicationId(applicationId);
        boolean success = jobApplicationService.sendInterviewInvitation(
                convertToEntity(applicationDTO), userPrincipal.getUserId());
        
        if (success) {
            return Result.success("面试邀请发送成功");
        }
        return Result.error("面试邀请发送失败");
    }

    @Operation(summary = "拒绝申请", description = "企业拒绝求职申请")
    @PostMapping("/{applicationId}/reject")
    @PreAuthorize("hasAnyRole('COMPANY', 'ADMIN')")
    public Result<Void> rejectApplication(@Parameter(description = "申请ID") @PathVariable Long applicationId,
                                        @RequestParam String rejectReason,
                                        @AuthenticationPrincipal UserPrincipal userPrincipal) {
        boolean success = jobApplicationService.rejectApplication(
                applicationId, rejectReason, userPrincipal.getUserId());
        
        if (success) {
            return Result.success("拒绝成功");
        }
        return Result.error("拒绝失败");
    }

    @Operation(summary = "录用申请者", description = "企业录用申请者")
    @PostMapping("/{applicationId}/hire")
    @PreAuthorize("hasAnyRole('COMPANY', 'ADMIN')")
    public Result<Void> hireApplicant(@Parameter(description = "申请ID") @PathVariable Long applicationId,
                                    @AuthenticationPrincipal UserPrincipal userPrincipal) {
        boolean success = jobApplicationService.hireApplicant(applicationId, userPrincipal.getUserId());
        
        if (success) {
            return Result.success("录用成功");
        }
        return Result.error("录用失败");
    }

    @Operation(summary = "用户申请统计", description = "查询用户申请统计数据")
    @GetMapping("/stats/user")
    @PreAuthorize("hasAnyRole('JOBSEEKER', 'ADMIN')")
    public Result<List<String>> getUserApplicationStats(@AuthenticationPrincipal UserPrincipal userPrincipal) {
        List<String> stats = jobApplicationService.getUserApplicationStats(userPrincipal.getUserId());
        return Result.success(stats);
    }

    @Operation(summary = "公司申请统计", description = "查询公司申请统计数据")
    @GetMapping("/stats/company/{companyId}")
    @PreAuthorize("hasAnyRole('COMPANY', 'ADMIN')")
    public Result<List<String>> getCompanyApplicationStats(@Parameter(description = "公司ID") @PathVariable Long companyId) {
        List<String> stats = jobApplicationService.getCompanyApplicationStats(companyId);
        return Result.success(stats);
    }

    @Operation(summary = "待处理申请数量", description = "查询公司待处理申请数量")
    @GetMapping("/pending-count/{companyId}")
    @PreAuthorize("hasAnyRole('COMPANY', 'ADMIN')")
    public Result<Integer> getPendingApplicationCount(@Parameter(description = "公司ID") @PathVariable Long companyId) {
        Integer count = jobApplicationService.getPendingApplicationCount(companyId);
        return Result.success(count);
    }

    @Operation(summary = "批量更新状态", description = "批量更新申请状态")
    @PostMapping("/batch-status")
    @PreAuthorize("hasAnyRole('COMPANY', 'ADMIN')")
    public Result<Void> batchUpdateStatus(@RequestBody List<Long> applicationIds,
                                        @RequestParam Integer status,
                                        @AuthenticationPrincipal UserPrincipal userPrincipal) {
        boolean success = jobApplicationService.batchUpdateStatus(applicationIds, status, userPrincipal.getUserId());
        if (success) {
            return Result.success("批量更新成功");
        }
        return Result.error("批量更新失败");
    }

    @Operation(summary = "批量删除申请", description = "批量删除申请记录")
    @DeleteMapping("/batch")
    @PreAuthorize("hasAnyRole('COMPANY', 'ADMIN')")
    public Result<Void> batchDeleteApplications(@RequestBody List<Long> applicationIds,
                                              @AuthenticationPrincipal UserPrincipal userPrincipal) {
        boolean success = jobApplicationService.batchDeleteApplications(applicationIds, userPrincipal.getUserId());
        if (success) {
            return Result.success("批量删除成功");
        }
        return Result.error("批量删除失败");
    }

    /**
     * DTO转实体
     */
    private JobApplication convertToEntity(JobApplicationDTO dto) {
        JobApplication entity = new JobApplication();
        BeanUtils.copyProperties(dto, entity);
        return entity;
    }
}